package com.klxedu.ms.gateway.security.filter;

import java.io.IOException;
import java.security.Principal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import com.klxedu.ms.gateway.AuthServerConstants;
import com.klxedu.ms.gateway.AuthServerProperties;
import com.klxedu.ms.gateway.security.exception.LoginCaptchaException;

public class CaptchaFilter extends OncePerRequestFilter {
	private AuthenticationEntryPoint authenticationEntryPoint;
	@Autowired
	private AuthServerProperties authServerProperties;

	public CaptchaFilter(AuthenticationEntryPoint authenticationEntryPoint) {
		this.authenticationEntryPoint = authenticationEntryPoint;
	}

	@Override
	public void afterPropertiesSet() {
		Assert.notNull(this.authenticationEntryPoint, "An AuthenticationEntryPoint is required");
	}

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		// 判断如果用户已登录，则返回
		// 未登录情况下，不是登录请求，无Authorization head头
		String sessionUserID = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_USERID);
		if (request.getHeader("Authorization") == null || !StringUtils.isEmpty(sessionUserID)) {
			filterChain.doFilter(request, response);
			return;
		}
		if (authServerProperties.isCaptcha()) {
			String url = request.getRequestURI();

			if (url.startsWith("/user/generateCaptchaNum") || url.startsWith("/user/generateCaptchaImage")) {
				filterChain.doFilter(request, response);
				return;
			}
			// 返回验证码
			String requestCaptcha = request.getParameter(AuthServerConstants.REQUEST_KEY_CAPTCHA);
			// session中获取验证码
			String sessionCaptcha = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_CAPTCHA);
			String generateTime = (String) request.getSession()
					.getAttribute(AuthServerConstants.SESSION_KEY_CAPTCHA_TIME);
			if (!StringUtils.isEmpty(generateTime)) {
				// 校验时间是否在有效期内
				SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date generateDate = null;
				try {
					generateDate = dateFormat.parse(generateTime);
					Date date = new Date();
					String nowDate = dateFormat.format(date);
					long time = (dateFormat.parse(nowDate)).getTime() - generateDate.getTime();
					if ((time / 1000) > authServerProperties.getCaptchaTimeout()) {// 校验时间为5秒
						failed(request, response, new LoginCaptchaException("验证码已超时。"));
						return;
					}
				} catch (ParseException e) {
					failed(request, response, new LoginCaptchaException("验证码校验失败。"));
					return;
				}
			}
			if (StringUtils.isEmpty(requestCaptcha)
					|| !requestCaptcha.toUpperCase().equals(sessionCaptcha.toUpperCase())) {
				failed(request, response, new LoginCaptchaException("验证码校验失败。"));
				return;
			}
			// 校验后清空session中的验证码
			request.getSession().removeAttribute(AuthServerConstants.SESSION_KEY_CAPTCHA);
			request.getSession().removeAttribute(AuthServerConstants.SESSION_KEY_CAPTCHA_TIME);
		}

		filterChain.doFilter(request, response);
	}

	private void failed(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
			throws IOException, ServletException {
		this.authenticationEntryPoint.commence(request, response, failed);
	}
}
